package com.atwisdom.star.aop;

import cn.hutool.core.util.StrUtil;
import com.atwisdom.star.common.util.DynamicDataSourceContextHolder;
import com.atwisdom.star.common.util.JwtUtils;
import com.atwisdom.star.common.vo.JsonResult;
import com.atwisdom.star.common.vo.StatusCode;
import com.atwisdom.star.exception.pojo.BusinessException;
import io.jsonwebtoken.Claims;
import jodd.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

/**
 * 动态数据源切面拦截
 */
@Slf4j
// @Aspect
// @Component
// @Order(1)
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class DynamicDataSourceAspect {

    /**
     * JWT的签发者
     **/
    @Value("${jwt.secret}")
    private String jwtSecret;

    @Around("execution(* com.atwisdom.star.controller.*.*(..)) || execution(* com.atwisdom.star.*.*(..))")
    public Object doAround(ProceedingJoinPoint jp) throws Throwable {
        ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        Object result = null;
        if (sra == null) {
            return null;
        }
        try {
            // 正常情况，应该优先从token取租户数据，临时兼容前台错误
            HttpServletRequest request = sra.getRequest();
            String tenantId = request.getHeader("Tenant_id");
            if (StringUtil.isEmpty(tenantId)) {
                tenantId = request.getParameter("Tenant_id");
            }
            if (StringUtil.isEmpty(tenantId)) {
                if (StrUtil.isNotBlank(request.getHeader("token")) && !"undefined".equals(request.getHeader("token"))) {
                    Claims claims = JwtUtils.parseJWT(request.getHeader("token"), jwtSecret);
                    tenantId = (String) claims.get("Tenant_id");
                }
            }
            log.info("当前租户Id:{}", tenantId);
            // 临时兼容前台错误，真实环境不应该有
            if (tenantId == null) {
                tenantId = "master";
            }
            if (!StringUtil.isEmpty(tenantId) && DynamicDataSourceContextHolder.containDataSourceKey(tenantId)) {
                DynamicDataSourceContextHolder.setDataSourceKey(tenantId);
                result = jp.proceed();
            } else {
                // result = JsonResult.error(StatusCode.NOT_EXIST_TENANT);
                throw new BusinessException(StatusCode.NOT_EXIST_TENANT.getMessage());
            }
        } finally {
            DynamicDataSourceContextHolder.clearDataSourceKey();
        }
        return result;
    }
}
